<template>
  <oolongSelect
    ref="select"
    class="oolong-auto-complete"
    :label="label"
    :disabled="disabled"
    :clearable="clearable"
    :placeholder="placeholder"
    :size="size"
    :placement="placement"
    filterable
    remote
    auto-complete
    :remote-method="remoteMethod"
    @on-change="handleChange"
    :transfer="transfer">
    <slot name="input">
      <oolongInput
        :element-id="elementId"
        ref="input"
        slot="input"
        v-model="currentValue"
        :name="name"
        :placeholder="placeholder"
        :disabled="disabled"
        :size="size"
        :icon="inputIcon"
        @on-click="handleClear"
        @on-focus="handleFocus"
        @on-blur="handleBlur"></oolongInput>
    </slot>
    <slot>
      <oolongOption v-for="item in filteredData" :value="item" :key="item">{{ item }}</oolongOption>
    </slot>
  </oolongSelect>
</template>
<script>
import oolongSelect from '../select';
import oolongOption from '../select/oolong-option.vue';
import oolongInput from '../input';
import {oneOf} from '../../utils/assist';
import Emitter from '../../mixins/emitter';

export default {
  name: 'AutoComplete',
  mixins: [Emitter],
  components: {oolongSelect, oolongOption, oolongInput},
  props: {
    value: {
      type: [String, Number],
      default: ''
    },
    label: {
      type: [String, Number],
      default: ''
    },
    data: {
      type: Array,
      default: () => []
    },
    disabled: {
      type: Boolean,
      default: false
    },
    clearable: {
      type: Boolean,
      default: false
    },
    placeholder: {
      type: String
    },
    size: {
      validator(value) {
        return oneOf(value, ['small', 'large', 'default']);
      }
    },
    icon: {
      type: String
    },
    filterMethod: {
      type: [Function, Boolean],
      default: false
    },
    placement: {
      validator(value) {
        return oneOf(value, ['top', 'bottom']);
      },
      default: 'bottom'
    },
    transfer: {
      type: Boolean,
      default: false
    },
    name: {
      type: String
    },
    elementId: {
      type: String
    }
  },
  data() {
    return {
      currentValue: this.value,
      disableEmitChange: false // for Form reset
    };
  },
  computed: {
    inputIcon() {
      let icon = '';
      if (this.clearable && this.currentValue) {
        icon = 'ios-close';
      } else if (this.icon) {
        icon = this.icon;
      }
      return icon;
    },
    filteredData() {
      if (this.filterMethod) {
        return this.data.filter(item => this.filterMethod(this.currentValue, item));
      } else {
        return this.data;
      }
    }
  },
  watch: {
    value(val) {
      if (this.currentValue !== val) {
        this.disableEmitChange = true;
      }
      this.currentValue = val;
    },
    currentValue(val) {
      this.$refs.select.query = val;
      this.$emit('input', val);
      if (this.disableEmitChange) {
        this.disableEmitChange = false;
        return;
      }
      this.$emit('on-change', val);
      this.dispatch('oolongFormItem', 'on-form-change', val);
    }
  },
  methods: {
    remoteMethod(query) {
      this.$emit('on-search', query);
    },
    handleChange(val) {
      this.currentValue = val;
      this.$refs.select.model = val;
      this.$refs.input.blur();
      this.$emit('on-select', val);
    },
    handleFocus(event) {
      this.$refs.select.visible = true;
      this.$emit('on-focus', event);
    },
    handleBlur(event) {
      this.$refs.select.visible = false;
      this.$emit('on-blur', event);
    },
    handleClear() {
      if (!this.clearable) return;
      this.currentValue = '';
      this.$refs.select.model = '';
    }
  }
};
</script>
